const getTwoMonthLater = () => {
  const d = new Date();
  d.setMonth(d.getMonth() + 2);
  return d.toUTCString()
};

const EVT_SET_TOKEN = 'set-token';

const setToken = (token: string): void => {
  try {
    window.localStorage.setItem('token', token);
  } catch (error) {
    // fallback to cookie if localStorage is somehow full or whatever.
    if (error instanceof DOMException) {
      document.cookie = `token=${encodeURIComponent(token)}; expires=${getTwoMonthLater()}; path=/; samesite=strict; secure`
    }
  } finally {
    window.dispatchEvent(new CustomEvent(EVT_SET_TOKEN));
  }
};

const getToken = (): string | undefined => {
  return (
    window.localStorage.getItem('token') ??
    document.cookie
      .split('; ')
      .find(row => row.startsWith('token='))
      ?.split('=')[1]
  );
};

const EVT_REMOVE_TOKEN = 'remove-token';

const removeToken = (): void => {
  window.localStorage.removeItem('token');
  const v = document.cookie
              .split('; ')
              .find(row => row.startsWith('token='))
  if (v) document.cookie = `token=`;
  window.dispatchEvent(new CustomEvent(EVT_REMOVE_TOKEN));
};

const listenSetToken = (cb: (...params: unknown[]) => void): void => {
  window.addEventListener(EVT_SET_TOKEN, cb);
};

const listenRemoveToken = (cb: (...params: unknown[]) => void): void => {
  window.addEventListener(EVT_REMOVE_TOKEN, cb);
};

export {
  setToken,
  getToken,
  removeToken,

  listenSetToken,
  listenRemoveToken
}